/*
 * copyright (c) 2013 Blaise-Florentin Collin
 *
 * This file is part of astroDCAM.
 *
 * AstroAviBrowser is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License v3
 * as published by the Free Software Foundation
 *
 * AstroAviBrowser is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * v3 along with AstroAviBrowser; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

///
/// \file dc1394bus.cpp
/// \brief Object wrapper for the dc1394 api (bus part) (code)
///

// C++ app includes
#include "config.hpp"
#include "dc1394bus.hpp"

// namespaces
using namespace std;

// public methods

//
// Main constructor
//
dc1394bus::dc1394bus() {
   TRACE("[dc1394bus] : Constructor")
   // init
   bus_handler=NULL;
   camera_list=NULL;

   // init the bus
   init();
}

//
// Main destructor
//
dc1394bus::~dc1394bus() {
   TRACE("[dc1394bus] : Destructor")
   clear();
}

//
// Reset the bus
//
void dc1394bus::reset() {
   TRACE("[dc1394bus] : Bus reset")
   cameraList.clear();
   clear();
   init();
}

//
// Number of camera on the bus
//
int dc1394bus::getCameraNumber() {
   if(camera_list)
      return(camera_list->num);
   return(-1);
}

///
/// Create, init and return a new camera object (must be released by user), NULL if failed
///
dc1394camera* dc1394bus::getCamera(uint64_t guid) {
   dc1394camera* cam;
   if(bus_handler==NULL)
      return(NULL);
   cam=new dc1394camera(bus_handler,guid);
   return(cam);
}


// private members

//
// Clear the bus
//
void dc1394bus::clear() {
   TRACE("[dc1394bus] : Clearing bus")
   // clear the camera list
   if(camera_list)
      dc1394_camera_free_list(camera_list);
   // clear the bus
   if(bus_handler)
      dc1394_free(bus_handler);
}

//
// Init the bus
//
void dc1394bus::init() {
   TRACE("[dc1394bus] : Init bus")

   // vars
   dc1394camera_t* cam;
   dc1394cameraId camId;
   dc1394error_t bus_error;

   // init the bus
   bus_handler=dc1394_new();
   if(bus_handler==NULL)
      TRACE("[dc1394bus] : Unable to init the ieee1394 bus")

   // list the cameras
   bus_error=dc1394_camera_enumerate(bus_handler,&camera_list);
   if(bus_error!=DC1394_SUCCESS)
      TRACE("[dc1394bus] : Unable to read the camera list" << " : error " << bus_error)

   TRACE("[dc1394bus] : " << camera_list->num << " cameras found")

   // fill the camera list
   for(int i=0;i< camera_list->num;i++) {
      cam=dc1394_camera_new(bus_handler,camera_list->ids[i].guid);
      camId.cameraVendor=string(cam->vendor);
      camId.cameraModel=string(cam->model);
      camId.cameraGuid=camera_list->ids[i].guid;
      cameraList.push_back(camId);
      TRACE("[dc1394bus] : Camera #" << i+1 << " Vendor : " << camId.cameraVendor << " Name : " << camId.cameraModel)
      dc1394_camera_free(cam);
   }
}
